package common.project.epic.ui;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.Resources;
import android.database.Cursor;
import android.location.Location;
import android.media.MediaRecorder;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcelable;
import android.os.RemoteException;
import android.provider.MediaStore;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RadioButton;
import android.widget.Toast;

import common.project.epic.core.IIOEpicService;
import common.project.epic.core.ILocationEpicService;
import common.project.epic.core.IOEpicService;
import common.project.epic.core.LocationEpicService;
import common.project.epic.db.CurrentUser;
import common.project.epic.db.EpicDBAdapter;
import common.project.epic.db.EpicNote;
import common.project.epic.db.FileExtensionMap;

public class EpicCreateMsg extends Activity implements OnClickListener, OnLongClickListener {
    
	
    private static final int HOP_COUNTER_0 = 0;
	
    
    // EpicCreateMsg Activity message content EditText
    private EditText msg_content_ET;
    
    
    // EpicCreateMsg Activity CATEGORIES ImageButton 
    // (click to show categories Dialog)
	private ImageButton categories_IB;
	// categories Dialog CheckBoxes
	private CheckBox general_CB;
	private CheckBox games_CB;
	private CheckBox advertisements_CB;
	private CheckBox suggestions_CB;
	private CheckBox events_CB;
	// categories Dialog dismiss() Button
	private Button dialogCategoriesDismissButton;
	// categories Dialog
	private Dialog dialogCategories;
	// categories Dialog ID
	private static final int DIALOG_CATEGORIES = 1;
	// categories IDs 
	private static final int GENERAL_CATEGORY = 1;
	private static final int GAMES_CATEGORY = 2;
	private static final int ADVERTISEMENTS_CATEGORY = 3;
	private static final int SUGGESTIONS_CATEGORY = 4;
	private static final int EVENTS_CATEGORY = 5;
	// categories constants
	public static final int NUMBER_OF_CATEGORIES = 16;
	private static final boolean[] DEFAULT_MSG_CATEGORIES = {true,false,false,false,
															false,false,false,false,
															false,false,false,false,
															false,false,false,false};
		
	// EpicCreateMsg Activity GEO PROPERTIES ImageButton 
	// (click to show geo properties Dialog)
	private ImageButton geo_IB;
	// geo properties Dialog LinearLayout 
	// (click to show MapView in order to set deferred message location if data connection is available)
	private ImageButton setGeoButton;
	// geo properties Dialog RadioButtons
	private RadioButton span1_RB;
	private RadioButton span2_RB;
	private RadioButton span3_RB;
	private RadioButton span4_RB;
	// geo properties Dialog dismiss() Button
	private Button dialogGeoDismissButton;
	// geo properties Dialog
	private Dialog dialogGeo;
	// geo properties Dialog ID
    private static final int DIALOG_GEO = 2;
//    // geo position item ID
//    private static final int GEO_POSITION = 1;
//    // geo span IDs
//    private static final int SPAN_BULDING = 2;
//    private static final int SPAN_QUARTER = 3;
//    private static final int SPAN_CITY = 4;
//    private static final int SPAN_WORLD = 5;
    // geo span constants
    private static final int SPAN_100m = 10; // [tens of meters]
	private static final int SPAN_1km = 100; // [tens of meters]
	private static final int SPAN_10km = 1000; // [tens of meters]
	private static final int SPAN_650km = 65000; // [tens of meters]
	
	private static final int MAP_SUBACTIVITY = 11;
	
    
	// EpicCreateMsg Activity TIME PROPERTIES ImageButton 
	// (click to show date picker Dialog)
	private ImageButton time_IB;
	// time properties Dialog ID
    private static final int DIALOG_TIME = 3;
    // expiration time constants 
    
    private static final long MAX_EXPIRATION_OFFSET_IN_SECONDS = 60*60*24*365; // 1 year
	
	
	// EpicCreateMsg Activity ATTACHMENT ImageButton 
	// (click to show attach file Dialog, lonClick to show (and remove if clicked) attachments)
	private ImageButton attach_IB;
	// attach a file IconContextMenu (Dialog)
    private IconContextMenu iconContextMenu_attachment;
	// attachment Dialog ID
    private static final int CONTEXT_MENU_ATTACHMENT_ID = 4;
    // attachment IDs
    protected final static int ATTACH_IMAGE = 1;
    protected final static int ATTACH_AUDIO = 2;
    protected final static int ATTACH_VIDEO = 3;
    protected final static int ATTACH_FILE = 4;
    // show (and remove if clicked) attachments IconContextMenu (Dialog)
    private IconContextMenu iconContextMenu_attachment_list;
    // attachments list Dialog ID
    private final int CONTEXT_MENU_ATTACHMENT_LIST_ID = 5;
    
	
	// EpicCreateMsg Activity VIRAL BUTTON
	// (click to make message viral)
	private Button viral_button;
	
	
	// categories variables
	private boolean[] msg_categories = new boolean[NUMBER_OF_CATEGORIES];

	// geo properties variable
	private int geo_span_value; // [tens of meters]
	
	private double default_latitude;
	private double default_longitude;
	private double default_altitude;
	
	private double last_latitude;
	private double last_longitude;
	private double last_altitude;
	
	private double msg_latitude;
	private double msg_longitude;
	private double msg_altitude;
	
    private Location currentLocation;
    
    private double currentLat;
	private double currentLon;
	private double currentAlt;
	
	private boolean deferredLocation = false;
	
	private int deferred_sending = 0;
    
    // set title Dialog
    private Dialog dialogTitle;
    // set title Dialog ID
    private static final int DIALOG_TITLE = 6;
    private EditText msg_title_ET;
    // title variable
    private String msg_title;
    // set title Dialog dismiss() Button
	private Button dialogTitleDismissButton;
	
	private IconContextMenu iconContextMenu_location;
	private final int CONTEXT_MENU_LOCATION_ID = 7;
	protected final static int DEFERRED_LOCATION = 1;
	protected final static int WITHOUT_LOCATION = 2;
	protected final static int DEFAULT_LOCATION = 3;
	protected final static int LAST_LOCATION = 4;
    
	// expiration time variables
    private int expire_year;
    private int expire_month;
    private int expire_day;
    private long expire_time_in_seconds;
    private long expire_time_in_millis;
    
    private Dialog datePicker;
    
    // attachment MIME type and URI string variables 
    private String extra_type;
    private String extra_content;
    private String[] extra_type_array;
    private String[] extra_content_array;
    
    private Resources res;
    
    private EpicDBAdapter dbHelper;
    private EpicNote epicNote;
    
    IOEpicService mCommService;
    LocationEpicService mLocationService;
    
    boolean mIOBound = false;
    boolean mLocBound = false;
	private ILocationEpicService mILocationEpicService = null;
	private IIOEpicService mIIOEpicService = null;
	private ServiceConnection mLocServiceConnection;
    
	private Calendar calendar;
    
    private static long MAX_MSG_SIZE = 5000000; // [bytes]
    private static long CONTENT_FIXED_PART_LENGTH = 61; // [bytes] 
    private static long MAX_TITLE_LENGTH = 80; // [bytes]
    private static long MAX_CONTENT_LENGTH = 1600; // [bytes]
    private long usedSpace = CONTENT_FIXED_PART_LENGTH + MAX_TITLE_LENGTH + MAX_CONTENT_LENGTH;
    
    private long[] attachmentsSize;
    
    String action;
    
    
    Timer recorderTimer;
    
    File audiotmp;
    FileOutputStream fos;
    private static boolean multipleBlow = false;
    MediaRecorder recorder;  
    private final static int BLOW_THRESHOLD = 28000;
    
	private class RecorderTask extends TimerTask {
		final Handler handler = new Handler();
		MediaRecorder recorder;
		public RecorderTask(MediaRecorder recorder) {
    	    this.recorder = recorder;
    	}
        public void run() {
            handler.post(new Runnable() {
                public void run() {
                	final int amplitude = recorder.getMaxAmplitude();
                	if(amplitude>BLOW_THRESHOLD && !multipleBlow) {
                		Log.d("", "amplitude is " + amplitude);
                		multipleBlow = true;
                		spreadSeed();
                	}
                }
            });
        }
    }
    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.epiccreatemsg);
        for(int i=0; i<DEFAULT_MSG_CATEGORIES.length; i++) {
        	msg_categories[i] = DEFAULT_MSG_CATEGORIES[i];
        	i++;
        }
        
        CurrentUser.readCurrentUserSettings(getApplicationContext());
        
        geo_span_value = CurrentUser.getDefaultMsgGeoSpan();
        
        Intent intentloc = new Intent(this, LocationEpicService.class);
    	mLocServiceConnection = new LocServiceConnection();
        if(bindService(intentloc, mLocServiceConnection, Context.BIND_AUTO_CREATE)){}
        else{
        	Log.d("EPIC CREATE MSG", "NOT BINDED TO LOCATION SERVICE");
        	Toast.makeText(getApplicationContext(), "Location not available", Toast.LENGTH_LONG).show();
        };
        
//        if(currentLat==0 && currentLon==0 && currentAlt==0) {
//	    	Intent intentloc = new Intent(this, LocationEpicService.class);
//	    	mLocServiceConnection = new LocServiceConnection();
//	        if(bindService(intentloc, mLocServiceConnection, Context.BIND_AUTO_CREATE)){}
//	        else{
//	        	Log.d("EPIC CREATE MSG", "NOT BINDED TO LOCATION SERVICE");
//	        };
//	        
//	        //set location
//	    	try {
//				currentLocation = (Location) mILocationEpicService.refreshLocation();
//				currentLat = currentLocation.getLatitude();
//				currentLon = currentLocation.getLongitude();
//				currentAlt = currentLocation.getAltitude();
//				msg_latitude = currentLocation.getLatitude();
//				msg_longitude = currentLocation.getLongitude();
//				msg_altitude = currentLocation.getAltitude();
//			} 
//			catch (Exception e) {
//				e.printStackTrace();
//			}
//	    	
//	    	if(currentLocation==null) {
//	    		Criteria criteria = new Criteria();
//	    		criteria.setAccuracy(Criteria.ACCURACY_COARSE);
//	    		criteria.setPowerRequirement(Criteria.POWER_LOW);
//	    		criteria.setAltitudeRequired(false);
//	    		criteria.setBearingRequired(false);
//	    		criteria.setSpeedRequired(false);
//	    		criteria.setCostAllowed(true);		
//	    		String context = Context.LOCATION_SERVICE;
//	    		LocationManager locationManager = (LocationManager)getSystemService(context);
//	    		String provider =  locationManager.getBestProvider(criteria, true);
//	    		while(provider== null){
//	    			try {
//						wait(1000);
//					} catch (InterruptedException e) {
//						// TODO Auto-generated catch block
//						e.printStackTrace();
//					}
//	    			provider =  locationManager.getBestProvider(criteria, true);
//
//	    		}
//	    		
//	    		currentLocation = locationManager.getLastKnownLocation(provider);
//	    		currentLat = currentLocation.getLatitude();
//				currentLon = currentLocation.getLongitude();
//				currentAlt = currentLocation.getAltitude();
//	    		msg_latitude = currentLocation.getLatitude();
//				msg_longitude = currentLocation.getLongitude();
//				msg_altitude = currentLocation.getAltitude();
//	    	}
//    	}
        
        
        //ACTION_SEND catching
        //check WHOIS calling intent
        //TODO check the reaction to intent calling and pass to initializeUI uri parameter, mime type parameter to fill each field
        //TODO add check for total file size: getFileSize method works only for MediaStore content provider files!
        Intent  callingIntent = getIntent();
        action = callingIntent.getAction();
        Bundle extras = callingIntent.getExtras();
        res = getResources();
        if(action != null){
	        if(action.equals("SHARE_TO_EPIC")) {
		        if(extras.containsKey("content")) {
		        	final Uri selectedUri = (Uri) extras.getParcelable("content");
		        	int mime_type = extras.getInt("mime_type");
		        	//####
	                String selectedPath = getPath(selectedUri, mime_type);
	                String fileExtension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(selectedPath);
	                long fSize = getFileSize(selectedUri, mime_type);
	                if(fSize>0  && FileExtensionMap.getSingelton().hasExtension(fileExtension)) {
		                usedSpace = usedSpace + fSize;
		                if(usedSpace>MAX_MSG_SIZE) {
		                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
		                			"Not enough space for this attachment!", Toast.LENGTH_LONG).show();
		                }
		                else {
		                	if(addExtraType(fileExtension, fSize)){
		                		addExtraContent(selectedPath);
		                	}
		                }
	                }
	                else {
	                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
	                			"Unable to attach this file!", Toast.LENGTH_LONG).show();
	                }
		        	//####
		        }
	        }
	        else if(action.equals("MULTIPLE_SHARE_TO_EPIC")) {
	        	if(extras.containsKey("content")) {
	        		ArrayList<Parcelable> selectedUri_list = extras.getParcelableArrayList("content");
		        	ArrayList<Integer> mime_type_list = extras.getIntegerArrayList("mime_type_list");
		        	//####
		        	int i=0;
		        	for(Integer item:mime_type_list) {
		        		Uri selectedUri = (Uri) selectedUri_list.get(i);
		        		int mime_type = (int) item;
		                String selectedPath = getPath(selectedUri, mime_type);
		                String fileExtension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(selectedPath);
		                long fSize = getFileSize(selectedUri, mime_type);
		                if(fSize>0  && FileExtensionMap.getSingelton().hasExtension(fileExtension)) {
			                usedSpace = usedSpace + fSize;
			                if(usedSpace>MAX_MSG_SIZE) {
			                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
			                			"Not enough space for this attachment!", Toast.LENGTH_LONG).show();
			                }
			                else {
			                	if(addExtraType(fileExtension, fSize)){
			                		addExtraContent(selectedPath);
			                	}
			                }
		                }
		                else {
		                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
		                			"Unable to attach this file!", Toast.LENGTH_LONG).show();
		                }
		                i++;
		        	}
		        	//####
		        }
    		}
    	}
    }
    
    @Override
    protected void onResume() {
    	super.onResume();
    	// initialize user interface
    	initializeUI();
    }
    
    @Override
    protected void onPause() {
    	if(recorderTimer!=null) {
    		recorderTimer.cancel();
    		recorderTimer = null;
    	}
    	if(recorder!=null) {
			recorder.reset();
			recorder = null;
		}
    	if(fos!=null) {
			try {
				fos.flush();
				fos.close();
				fos = null;
				audiotmp.delete();
				audiotmp = null;
			} catch (IOException e2) {
				e2.printStackTrace();
			}
    	}
    	super.onPause();
    }
    
    @Override
    protected void onStop() {
    	// Unbind from the service
        if (mLocBound) {
            unbindService(mLocServiceConnection);
            mLocBound = false;
        }
        if (mIOBound) {
            unbindService(mIOServiceConnection);
            mIOBound = false;
        }
        super.onStop();
    }
    
    //########################################
    //##      SERVICE CONNECTIONS           ##
    //########################################
    class LocServiceConnection implements ServiceConnection{
    	public void onServiceConnected(ComponentName component, IBinder service) {
    		mILocationEpicService = ILocationEpicService.Stub.asInterface(service);
    	}
    	
    	public void onServiceDisconnected(ComponentName component) {
    		mLocBound = false;
    	}
    };
    
    ServiceConnection mIOServiceConnection = new ServiceConnection() {
    	public void onServiceConnected(ComponentName component, IBinder service) {
    		mIIOEpicService = IIOEpicService.Stub.asInterface(service);
    	}
    	public void onServiceDisconnected(ComponentName component) {
    		mIOBound = false;
    	}
    };
    
    

    
    //###############################################################
    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
    	// Save UI state changes to the savedInstanceState.
    	// This bundle will be passed to onCreate if the process is
    	// killed and restarted.
    	savedInstanceState.putLong("expire_time_in_seconds", expire_time_in_seconds);
    	savedInstanceState.putInt("geo_span_value", geo_span_value); // [tens of meters]
    	savedInstanceState.putString("extra_type", extra_type);
    	savedInstanceState.putString("extra_content", extra_content);
    	
    	savedInstanceState.putInt("expire_year", expire_year);
    	savedInstanceState.putInt("expire_month", expire_month);
    	savedInstanceState.putInt("expire_day", expire_day);
    	
    	savedInstanceState.putBooleanArray("msg_categories", msg_categories);
    	
    	savedInstanceState.putLongArray("attachmentsSize", attachmentsSize);
    	savedInstanceState.putLong("usedSpace", usedSpace);
    	
    	savedInstanceState.putDouble("msg_latitude", msg_latitude);
    	savedInstanceState.putDouble("msg_longitude", msg_longitude);
    	savedInstanceState.putDouble("msg_altitude", msg_altitude);
    	savedInstanceState.putDouble("currentLat", currentLat);
    	savedInstanceState.putDouble("currentLon", currentLon);
    	savedInstanceState.putDouble("currentAlt", currentAlt);
    	
    	savedInstanceState.putString("msg_title", msg_title);
    	
    	super.onSaveInstanceState(savedInstanceState);
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
    	super.onRestoreInstanceState(savedInstanceState);
    	// Restore UI state from the savedInstanceState.
    	// This bundle has also been passed to onCreate. 
    	attachmentsSize = savedInstanceState.getLongArray("attachmentsSize"); 
    	usedSpace = savedInstanceState.getLong("usedSpace");
    	
    	expire_time_in_seconds = savedInstanceState.getLong("expire_time_in_seconds");
    	geo_span_value = savedInstanceState.getInt("geo_span_value"); // [tens of meters]
    	extra_type = savedInstanceState.getString("extra_type");
    	extra_content = savedInstanceState.getString("extra_content");    	
    	
    	if(!(extra_type==null && extra_content==null)) {
    		extra_type_array = extra_type.split(",");
    		extra_content_array = extra_content.split(",");
    		int count_occurrence = extra_content_array.length;
    		
    		if(iconContextMenu_attachment_list==null) {
				iconContextMenu_attachment_list = new IconContextMenu(this, CONTEXT_MENU_ATTACHMENT_LIST_ID);
				for(int i=0; i<count_occurrence; i++) {
	    			iconContextMenu_attachment_list.addItem(res, extra_content_array[i], R.drawable.icon, i);
	    		}
			}
    	}

    	expire_year = savedInstanceState.getInt("expire_year");
    	expire_month = savedInstanceState.getInt("expire_month");
    	expire_day = savedInstanceState.getInt("expire_day");
        
        msg_categories = savedInstanceState.getBooleanArray("msg_categories");
        
        msg_latitude = savedInstanceState.getDouble("msg_latitude");
        msg_longitude = savedInstanceState.getDouble("msg_longitude");
        msg_altitude = savedInstanceState.getDouble("msg_altitude");
        currentLat = savedInstanceState.getDouble("currentLat");
        currentLon = savedInstanceState.getDouble("currentLon");
        currentAlt = savedInstanceState.getDouble("currentAlt");
        
        msg_title = savedInstanceState.getString("msg_title");
    }
    //###############################################################
    
    
    private void initializeUI() {
    	
    	CurrentUser.readCurrentUserSettings(getApplicationContext());
    	
        dbHelper = new EpicDBAdapter(this);
    	
    	msg_content_ET = (EditText)findViewById(R.id.epicmsg_note_ET);
    	categories_IB = (ImageButton)findViewById(R.id.categories_IB);
    	geo_IB = (ImageButton)findViewById(R.id.geo_IB);
    	time_IB = (ImageButton)findViewById(R.id.time_IB);
    	attach_IB = (ImageButton)findViewById(R.id.attach_IB);
    	
    	categories_IB.setOnClickListener(this);
    	geo_IB.setOnClickListener(this);
    	time_IB.setOnClickListener(this);
    	attach_IB.setOnClickListener(this);
    	attach_IB.setOnLongClickListener(this);
    	
    	viral_button = (Button)findViewById(R.id.epicmsg_viralButton);

        // make message viral 
	    viral_button.setOnClickListener(this);
	    
    }
    
    
    //#############################//
    // attachments utility methods // 
    //#############################//
    private void attachImage() {
    	Intent intent = new Intent();
    	intent.setType("image/*");
    	intent.setAction(Intent.ACTION_GET_CONTENT);
    	startActivityForResult(Intent.createChooser(intent, "Select image"), ATTACH_IMAGE);
    }
    
    private void attachAudio() {
    	Intent intent = new Intent();
    	intent.setType("audio/*");
    	intent.setAction(Intent.ACTION_GET_CONTENT);
    	startActivityForResult(Intent.createChooser(intent, "Select audio"), ATTACH_AUDIO);
    }
    
    private void attachVideo() {
    	Intent intent = new Intent();
    	intent.setType("video/*");
    	intent.setAction(Intent.ACTION_GET_CONTENT);
    	startActivityForResult(Intent.createChooser(intent, "Select video"), ATTACH_VIDEO);
    }
    
    private void attachFile() {
//    	Toast.makeText(getApplicationContext(), "attach generic file not yet available", Toast.LENGTH_LONG).show();
    	Intent intent = new Intent();
    	intent.setType("*/*");
    	intent.setAction(Intent.ACTION_GET_CONTENT);
    	startActivityForResult(Intent.createChooser(intent, "Select file"), ATTACH_FILE);
    }
    
    public long getFileSize(Uri uri, int type){
 	   //return the size in bytes of the file attacched to the URI passed as method's argument
    	long filesize = 0;
    	String uri_string = getPath(uri, type);
    	File attached_file = new File(uri_string);
    	if(attached_file.exists()) {
    		filesize = attached_file.length();
    	}
    	else {
    		uri_string = "file://" + uri_string;
    		attached_file = new File(uri_string);
    		if(attached_file.exists()) {
    			filesize = attached_file.length();
    		}
    	}
 	    return filesize;
 	}
    
    public String getPath(Uri uri, int type) {
    	String path = null;
        File tmp_file = new File(uri.getPath());
        if(tmp_file.exists()){
                path = uri.getPath();
        }
        else{
        	if(type==ATTACH_IMAGE) {
        		String[] projection = { MediaStore.Images.Media.DATA };
                Cursor cursor = managedQuery(uri, projection, null, null, null);
                if(cursor!=null){
                        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                        cursor.moveToFirst();
                        path = cursor.getString(column_index);
                }
        	}
        	if(type==ATTACH_AUDIO) {
        		String[] projection = { MediaStore.Audio.Media.DATA };
                Cursor cursor = managedQuery(uri, projection, null, null, null);
                if(cursor!=null){
                        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
                        cursor.moveToFirst();
                        path = cursor.getString(column_index);
                }
        	}
        	if(type==ATTACH_VIDEO) {
        		String[] projection = { MediaStore.Video.Media.DATA };
                Cursor cursor = managedQuery(uri, projection, null, null, null);
                if(cursor!=null){
                        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
                        cursor.moveToFirst();
                        path = cursor.getString(column_index);
                }
        	}
        	if(type==ATTACH_FILE) {
        		if ("content".equalsIgnoreCase(uri.getScheme())) {
                    String[] projection = { "_data" };
                    Cursor cursor = null;
                    try {
                        cursor = getApplicationContext().getContentResolver().query(uri, projection, null, null, null);
                        int column_index = cursor.getColumnIndexOrThrow("_data");
                        if (cursor.moveToFirst()) {
                            path = cursor.getString(column_index);
                        }
                    } catch (Exception e) {}
                }
                else if ("file".equalsIgnoreCase(uri.getScheme())) {
                    path = uri.getPath();
                }
        	}
        }
        return path;
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent returnedIntent) { 
        super.onActivityResult(requestCode, resultCode, returnedIntent);         
        switch(requestCode) { 
        	case ATTACH_IMAGE: {
	            if(resultCode == RESULT_OK) {  
	                Uri selectedUri = returnedIntent.getData();
	                String selectedPath = getPath(selectedUri, ATTACH_IMAGE);
	                String fileExtension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(selectedPath); 
//	                String mimeType = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
	                long fSize = getFileSize(selectedUri, ATTACH_IMAGE);
	                if(fSize>0 && FileExtensionMap.getSingelton().hasExtension(fileExtension)) {
		                usedSpace = usedSpace + fSize;
		                if(usedSpace>MAX_MSG_SIZE) {
		                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
		                			"Not enough space for this attachment!", Toast.LENGTH_LONG).show();
		                }
		                else {
		                	if(addExtraType(fileExtension, fSize)){
		                		addExtraContent(selectedPath);
		                	}
		                }
	                }
	                else {
	                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
	                			"Unable to attach this file!", Toast.LENGTH_LONG).show();
	                }
	            }
	            break;
        	}
        	case ATTACH_AUDIO: {
        		if(resultCode == RESULT_OK) {
        			Uri selectedUri = returnedIntent.getData();
	                String selectedPath = getPath(selectedUri, ATTACH_AUDIO);
	                String fileExtension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(selectedPath); 
//	                String mimeType = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
	                long fSize = getFileSize(selectedUri, ATTACH_AUDIO);
	                if(fSize>0  && FileExtensionMap.getSingelton().hasExtension(fileExtension)) {
		                usedSpace = usedSpace + fSize;
		                if(usedSpace>MAX_MSG_SIZE) {
		                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
		                			"Not enough space for this attachment!", Toast.LENGTH_LONG).show();
		                }
		                else {
		                	if(addExtraType(fileExtension, fSize)){
		                		addExtraContent(selectedPath);
		                	}
		                }
	                }
	                else {
	                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
	                			"Unable to attach this file!", Toast.LENGTH_LONG).show();
	                }
        		}
        		break;
        	}
        	case ATTACH_VIDEO: {
        		if(resultCode == RESULT_OK) {
        			Uri selectedUri = returnedIntent.getData();
	                String selectedPath = getPath(selectedUri, ATTACH_VIDEO);
	                String fileExtension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(selectedPath); 
//	                String mimeType = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
	                long fSize = getFileSize(selectedUri, ATTACH_VIDEO);
	                if(fSize>0  && FileExtensionMap.getSingelton().hasExtension(fileExtension)) {
		                usedSpace = usedSpace + fSize;
		                if(usedSpace>MAX_MSG_SIZE) {
		                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
		                			"Not enough space for this attachment!", Toast.LENGTH_LONG).show();
		                }
		                else {
		                	if(addExtraType(fileExtension, fSize)){
		                		addExtraContent(selectedPath);
		                	}
		                }
	                }
	                else {
	                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
	                			"Unable to attach this file!", Toast.LENGTH_LONG).show();
	                }
        		}
        		break;
        	}
        	case ATTACH_FILE: {
        		if(resultCode == RESULT_OK) {  
	                Uri selectedUri = returnedIntent.getData();
	                String selectedPath = getPath(selectedUri, ATTACH_FILE);
	                String fileExtension = android.webkit.MimeTypeMap.getFileExtensionFromUrl(selectedPath); 
//	                String mimeType = android.webkit.MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
	                long fSize = getFileSize(selectedUri, ATTACH_FILE);
	                if(fSize>0  && FileExtensionMap.getSingelton().hasExtension(fileExtension)) {
		                usedSpace = usedSpace + fSize;
		                if(usedSpace>MAX_MSG_SIZE) {
		                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
		                			"Not enough space for this attachment!", Toast.LENGTH_LONG).show();
		                }
		                else {
		                	if(addExtraType(fileExtension, fSize)){
		                		addExtraContent(selectedPath);
		                	}
		                }
	                }
	                else {
	                	Toast.makeText(getApplicationContext(), "Sorry!\n" +
	                			"Unable to attach this file!", Toast.LENGTH_LONG).show();
	                }
	            }
        		break;
        	}
        	case MAP_SUBACTIVITY: {
        		if(resultCode == RESULT_OK) {
        			msg_latitude = returnedIntent.getDoubleExtra("outLat", 0);
        			msg_longitude = returnedIntent.getDoubleExtra("outLon", 0);
        			deferredLocation = true;
        		}
        		else {}
        		break;
        	}
        }
    }
    
    private boolean addExtraType(String type, long fileSize) {
    	if(extra_type != null) {
    		extra_type = extra_type + "," + type;
    		long[] sizeArrayTmp = new long[(extra_type.split(",")).length];
    		int i = 0;
    		for(long item:attachmentsSize) {
    			sizeArrayTmp[i] = item;
    			i++;
    		}
    		sizeArrayTmp[i] = fileSize;
    		
    		attachmentsSize = new long[sizeArrayTmp.length];
    		i = 0;
    		for(long item:sizeArrayTmp) {
    			sizeArrayTmp[i] = item;
    			i++;
    		}
    	}
    	else {
    		extra_type = type;
    		attachmentsSize = new long[1];
    		attachmentsSize[0] = fileSize;
    	}
		extra_type_array = extra_type.split(",");
		return true;
    }
    private void addExtraContent(String uri_string) {
    	if(extra_content != null) {
    		extra_content = extra_content + "," + uri_string;
    	}
    	else {
    		extra_content = uri_string;
    	}
    	extra_content_array = extra_content.split(",");
    	int count_occurrence = extra_content_array.length;
    	
    	if(iconContextMenu_attachment_list==null) {
			iconContextMenu_attachment_list = new IconContextMenu(this, CONTEXT_MENU_ATTACHMENT_LIST_ID);
		}
    	iconContextMenu_attachment_list.addItem(res, uri_string, R.drawable.icon, count_occurrence-1);
    }

    public void spreadSeed() {
    	boolean cat_selected = false;
		for(boolean item : msg_categories) {
			if(item) {cat_selected = true; break;}
		}
		if(usedSpace>=MAX_MSG_SIZE) {
			Toast.makeText(getApplicationContext(), "To much space used", Toast.LENGTH_LONG).show();
		}
		else {
			if(!cat_selected) {
    			Toast.makeText(getApplicationContext(), "Check at least one category!", Toast.LENGTH_LONG).show();
    		}
    		else {
    			try {
    				currentLocation = (Location) mILocationEpicService.refreshLocation();
    			} 
    			catch (Exception e) {
    				e.printStackTrace();
    			}
    			
    			
    			if(currentLocation!=null) {
    				currentLat = currentLocation.getLatitude();
    				currentLon = currentLocation.getLongitude();
    				currentAlt = currentLocation.getAltitude();
    				if(deferredLocation) {}
    				else {
    					msg_latitude = currentLocation.getLatitude();
        				msg_longitude = currentLocation.getLongitude();
        				msg_altitude = currentLocation.getAltitude();
    				}
    				setEpicNote();
    			}
    			else {
//    				Toast.makeText(getApplicationContext(), "No Location Available \n" +
//        					"please activate GPS, WiFi or GPRS", Toast.LENGTH_LONG).show();
    				// show dialog with the following options
    				// 1) deferred sending (as soon as a location is available)
    				// 2) without location
    				// 3) use default location
    				// 4) use last location
    				
    				if(recorderTimer!=null) {
    		    		recorderTimer.cancel();
    		    		recorderTimer = null;
    		    	}
    		    	if(recorder!=null) {
    					recorder.reset();
    					recorder = null;
    				}
    		    	if(fos!=null) {
	    				try {
	    					fos.flush();
	    					fos.close();
	    					fos = null;
	    					audiotmp.delete();
	    					audiotmp = null;
	    				} catch (IOException e2) {
	    					e2.printStackTrace();
	    				}
    		    	}
    				
    				showLocationMenu();
    			}
    		}
		}
    }
    
    public void setEpicNote() {
    	epicNote = new EpicNote();
		Date date = new Date();
		long t_now_seconds = date.getTime()/1000;
		if(expire_time_in_seconds<t_now_seconds) {
			expire_time_in_seconds = t_now_seconds + CurrentUser.getDefaultMsgTimeSpan();
		}
		String user_mac_string = BluetoothAdapter.getDefaultAdapter().getAddress();
		String[] user_mac_string_array = user_mac_string.split(":");
		epicNote.setNoteId("" + user_mac_string_array[4] + user_mac_string_array[5] + t_now_seconds);
		epicNote.setExpireTimeInSeconds(expire_time_in_seconds);
		epicNote.setAltitude(msg_altitude);
		epicNote.setLongitude(msg_longitude);
		epicNote.setLatitude(msg_latitude);
		
		epicNote.setGeoSpan(geo_span_value);
		epicNote.setNoteCategory(msg_categories);
		epicNote.setNoteCreatorId(CurrentUser.getCurrentUsername());
		if(msg_title==null) {
			if(msg_content_ET.getText().toString()==null) {
				msg_title = "";
			}
			else {
				String tmp = msg_content_ET.getText().toString();
				if(tmp.length()>MAX_TITLE_LENGTH) {
					msg_title = (tmp).substring(0, (int) MAX_TITLE_LENGTH);
				}
				else {
					msg_title = tmp;
				}
			}
		}
		epicNote.setNoteTitle(msg_title);
		epicNote.setNoteContent(msg_content_ET.getText().toString());
		epicNote.setExtraType(extra_type);
		epicNote.setExtraContent(extra_content);
	            
        dbHelper.open();
        Log.d("ATTENTION", "use EpicNewMsg instead of EpicCreateMsg");
//		dbHelper.addContent(epicNote, 
//	    		HOP_COUNTER_0, 
//	    		CurrentUser.getCurrentUsername(), t_now_seconds, 
//	    		currentLat, currentLon, currentAlt, 
//	    		CurrentUser.getCurrentUsername(), deferred_sending);
		dbHelper.close();
//		Toast.makeText(getApplicationContext(), "Make message VIRAL", Toast.LENGTH_LONG).show();
		finish();
    }

	@Override
	public void onClick(View v) {

		if(v.getId() == R.id.epicmsg_viralButton) {
			
			Toast.makeText(getApplicationContext(), "BLOW ON THE MICROPHONE\nTO SPRINKLE THE MESSAGE", Toast.LENGTH_LONG).show();
			
			if(recorderTimer!=null) {
	    		recorderTimer.cancel();
	    		recorderTimer = null;
	    	}
	    	recorderTimer = new Timer();
	    	
	    	if(recorder!=null) {
	    		recorder.release();
	    		recorder = null;
	    	} 
	    	recorder = new MediaRecorder();
	    	
	    	multipleBlow = false;
	    	
	    	recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
	    	recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
	        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
	        File path = getApplicationContext().getExternalCacheDir();
	        audiotmp = new File(path, "audio_tmp");
			try {
				fos = new FileOutputStream(audiotmp);
				recorder.setOutputFile(fos.getFD());
			} catch (Exception e1) {
				e1.printStackTrace();
			}
	    	 try {
				recorder.prepare();
			} catch (IllegalStateException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} 
	        recorder.start();
	        
	    	recorderTimer.schedule(new RecorderTask(recorder), 0, 250);
    	}
		
		if(v.getId() == R.id.categories_IB) {
			showCategoriesDialog();
		}
		if(v.getId() == R.id.general_CB) {
			msg_categories[0] = general_CB.isChecked() ? true : false; 
		}
		if(v.getId() == R.id.games_CB) {
			msg_categories[1] = games_CB.isChecked() ? true : false;
		}
		if(v.getId() == R.id.advertisements_CB) {
			msg_categories[2] = advertisements_CB.isChecked() ? true : false;
		}
		if(v.getId() == R.id.suggestions_CB) {
			msg_categories[3] = suggestions_CB.isChecked() ? true : false;
		}
		if(v.getId() == R.id.events_CB) {
			msg_categories[4] = events_CB.isChecked() ? true : false;
		}
		if(v.getId() == R.id.dialogCategoriesDismissButton) {
			dialogCategories.dismiss();
		}
		
		
		if(v.getId() == R.id.geo_IB) {
			showGeoDialog();
		}
		if(v.getId() == R.id.setGeoButton) {
			if(isOnline()) {
				try {
					currentLocation = (Location) mILocationEpicService.refreshLocation();
				} 
				catch (Exception e) {
					e.printStackTrace();
				}
				if(currentLocation!=null) {
					if(deferredLocation) {
						// DO NOTHING
					}
					else {
						msg_latitude = currentLocation.getLatitude();
        				msg_longitude = currentLocation.getLongitude();
        				msg_altitude = currentLocation.getAltitude();
					}
					Intent mapIntent = new Intent(this, EpicMapActivity.class);
					mapIntent.putExtra("inLat", msg_latitude);
					mapIntent.putExtra("inLon", msg_longitude);
					mapIntent.putExtra("settableMsgPosition", true);
					startActivityForResult(mapIntent, MAP_SUBACTIVITY);
				}
				else {
					Toast.makeText(getApplicationContext(), "No Location Available \n" +
        					"please activate GPS or WiFi", Toast.LENGTH_LONG).show();
				}
			}
			else {
				Toast.makeText(getApplicationContext(), "to set message position property \n" +
						"data connection is needed", Toast.LENGTH_LONG).show();
			}
		}
		if(v.getId() == R.id.span1_RB) {
			span1_RB.setChecked(true); span2_RB.setChecked(false); span3_RB.setChecked(false); span4_RB.setChecked(false);
			geo_span_value = SPAN_100m;
		}
		if(v.getId() == R.id.span2_RB) {
			span1_RB.setChecked(false); span2_RB.setChecked(true); span3_RB.setChecked(false); span4_RB.setChecked(false);
			geo_span_value = SPAN_1km;
		}
		if(v.getId() == R.id.span3_RB) {
			span1_RB.setChecked(false); span2_RB.setChecked(false); span3_RB.setChecked(true); span4_RB.setChecked(false);
			geo_span_value = SPAN_10km;
		}
		if(v.getId() == R.id.span4_RB) {
			span1_RB.setChecked(false); span2_RB.setChecked(false); span3_RB.setChecked(false); span4_RB.setChecked(true);
			geo_span_value = SPAN_650km;
		}
		if(v.getId() == R.id.dialogGeoDismissButton) {
			dialogGeo.dismiss();
		}
		
		if(v.getId() == R.id.time_IB) {
			showTimeDialog();
		}
		if(v.getId() == R.id.attach_IB) {
			showAttachmentMenu();
		}
		
		if(v.getId() == R.id.dialogTitleDismissButton) {
			msg_title = msg_title_ET.getText().toString();
			dialogTitle.dismiss();
		}
	}
	@Override
	public void finish(){
		super.finish();
		if(action != null) {
			if(action.equals("SHARE_TO_EPIC") || action.equals("MULTIPLE_SHARE_TO_EPIC")) {
				Intent i  = new Intent(EpicCreateMsg.this,Epic.class);
				startActivity(i);
			}
		}
	}
	@Override
	public boolean onLongClick(View v) {
		if(v.getId() == R.id.attach_IB) {
			if(extra_content==null && extra_type==null) {
				Toast.makeText(getApplicationContext(), "There are no attached files", Toast.LENGTH_LONG).show();
			}
			else {
				showAttachmentList();
			}
		}
		return true;
	}
	
	//########################################
    //## SIMULATE CONTEXT MENU USING DIALOG ##
    //########################################	
    @Override
    protected Dialog onCreateDialog(int id) {
    	
    	if(id == DIALOG_CATEGORIES) {
    		if(dialogCategories==null) {
    			dialogCategories = new Dialog(this,R.style.CatDialog);
    			dialogCategories.setContentView(R.layout.set_msg_categories_dialog);
    			dialogCategories.setTitle("Set categories");
                
                general_CB = (CheckBox)dialogCategories.findViewById(R.id.general_CB);
        		games_CB = (CheckBox)dialogCategories.findViewById(R.id.games_CB);
        		advertisements_CB = (CheckBox)dialogCategories.findViewById(R.id.advertisements_CB);
        		suggestions_CB = (CheckBox)dialogCategories.findViewById(R.id.suggestions_CB);
        		events_CB = (CheckBox)dialogCategories.findViewById(R.id.events_CB);
        		dialogCategoriesDismissButton = (Button)dialogCategories.findViewById(R.id.dialogCategoriesDismissButton);
        		
        		general_CB.setOnClickListener(this);
        		games_CB.setOnClickListener(this);
        		advertisements_CB.setOnClickListener(this);
        		suggestions_CB.setOnClickListener(this);
        		events_CB.setOnClickListener(this);
        		dialogCategoriesDismissButton.setOnClickListener(this);
        	}
    		for(int i=0; i<msg_categories.length; i++) {
    			if(msg_categories[i]) {
    				switch(i+1) {
                    	case GENERAL_CATEGORY: { general_CB.setChecked(true); break; }
                    	case GAMES_CATEGORY: { games_CB.setChecked(true); break; }
                    	case ADVERTISEMENTS_CATEGORY: { advertisements_CB.setChecked(true); break; }
                    	case SUGGESTIONS_CATEGORY: { suggestions_CB.setChecked(true); break; }
                    	case EVENTS_CATEGORY: { events_CB.setChecked(true); break; }
                    	default : { break; }
                    }
    			}
    			else {
    				switch(i+1) {
                    	case GENERAL_CATEGORY: { general_CB.setChecked(false); break; }
                    	case GAMES_CATEGORY: { games_CB.setChecked(false); break; }
                    	case ADVERTISEMENTS_CATEGORY: { advertisements_CB.setChecked(false); break; }
                    	case SUGGESTIONS_CATEGORY: { suggestions_CB.setChecked(false); break; }
                    	case EVENTS_CATEGORY: { events_CB.setChecked(false); break; }
                    	default : { break; }
                    }
    			}
    		}
    		
    		return dialogCategories;
    	}
    	
    	
    	
    	if(id == DIALOG_GEO) {
    		if(dialogGeo==null) {
                dialogGeo = new Dialog(this,R.style.GeoDialog);
    			dialogGeo.setContentView(R.layout.set_geo_properties_dialog);
    			dialogGeo.setTitle("GEO properties");    			
                setGeoButton = (ImageButton)dialogGeo.findViewById(R.id.setGeoButton); 
                span1_RB = (RadioButton)dialogGeo.findViewById(R.id.span1_RB);
        		span2_RB = (RadioButton)dialogGeo.findViewById(R.id.span2_RB);
        		span3_RB = (RadioButton)dialogGeo.findViewById(R.id.span3_RB);
        		span4_RB = (RadioButton)dialogGeo.findViewById(R.id.span4_RB);
        		dialogGeoDismissButton = (Button)dialogGeo.findViewById(R.id.dialogGeoDismissButton);
        		
        		setGeoButton.setOnClickListener(this);
        		span1_RB.setOnClickListener(this);
        		span2_RB.setOnClickListener(this);
        		span3_RB.setOnClickListener(this);
        		span4_RB.setOnClickListener(this);
        		dialogGeoDismissButton.setOnClickListener(this);
        	}
    		
    		switch(geo_span_value) {
	        	case SPAN_100m: { 
	        		span1_RB.setChecked(true); span2_RB.setChecked(false); span3_RB.setChecked(false); span4_RB.setChecked(false);
	    			geo_span_value = SPAN_100m;
	        		break; 
	        	}
	        	case SPAN_1km: { 
	        		span1_RB.setChecked(false); span2_RB.setChecked(true); span3_RB.setChecked(false); span4_RB.setChecked(false);
	    			geo_span_value = SPAN_1km;
	    			break;
	    		}
	        	case SPAN_10km: {
	    			span1_RB.setChecked(false); span2_RB.setChecked(false); span3_RB.setChecked(true); span4_RB.setChecked(false);
	    			geo_span_value = SPAN_10km;
	    			break;
	    		}
	        	case SPAN_650km: {
	    			span1_RB.setChecked(false); span2_RB.setChecked(false); span3_RB.setChecked(false); span4_RB.setChecked(true);
	    			geo_span_value = SPAN_650km;
	    			break;
	    		}
	        	default : { break; }
    		}
    		return dialogGeo;
        }
    	
    	
    	if(id == DIALOG_TIME) {
    		if(datePicker==null) {
    			if(expire_year==0) {
    				CurrentUser.readCurrentUserSettings(getApplicationContext());
    				Date date = new Date();
    				expire_time_in_seconds = (date.getTime()/1000) + CurrentUser.getDefaultMsgTimeSpan();
    				Date expire_date = new Date(expire_time_in_seconds*1000);
    				
    				calendar = Calendar.getInstance();
    				calendar.setTime(expire_date);
    				
        	        expire_year = calendar.get(Calendar.YEAR);
        	        expire_month = calendar.get(Calendar.MONTH);
        	        expire_day = calendar.get(Calendar.DAY_OF_MONTH);
    			}
    			datePicker = new DatePickerDialog(this, mDateSetListener, expire_year, expire_month, expire_day);
    			datePicker.setTitle("Set withering");
    		} 
    		else {
    			// DO NOTHING
    		} 
        	return datePicker; 
        }
    	
    	
    	
    	if(id == CONTEXT_MENU_ATTACHMENT_ID) {
    		if(iconContextMenu_attachment==null) {
    	    	//initialize the ATTACHMENT context menu
    		    iconContextMenu_attachment = new IconContextMenu(this, CONTEXT_MENU_ATTACHMENT_ID);
    		    iconContextMenu_attachment.addItem(res, R.string.attach_image, R.drawable.icon, ATTACH_IMAGE);
    		    iconContextMenu_attachment.addItem(res, R.string.attach_audio, R.drawable.icon, ATTACH_AUDIO);
    		    iconContextMenu_attachment.addItem(res, R.string.attach_video, R.drawable.icon, ATTACH_VIDEO);
    		    iconContextMenu_attachment.addItem(res, R.string.attach_file, R.drawable.icon, ATTACH_FILE);
    		    /*
    		     * ABOUT THE COMMENTED @Override ANNOTATION 
    		     * An IconContextMenu object IMPLEMENTS DialogInterface.OnCancelListener, DialogInterface.OnDismissListener 
    		     * (http://stackoverflow.com/questions/4761888/override-annotation-error-android-prefs):
    		     * In Java 5 vs Java 6 they changed whether you could use "Override" with an interface 
    		     * (since Override seems to imply that you are overriding some sort of default behavior, 
    		     * which you are not doing with an interface!). If you so desire, you can search 
    		     * in the Eclipse preferences and change it from a compilation error to a compilation warning.
    		     */
        	}
    	    iconContextMenu_attachment.setOnClickListener(new IconContextMenu.IconContextMenuOnClickListener() {
//    	    	@Override
                public void onClick(int menuId) {
    	    		switch(menuId) {
                    	case ATTACH_IMAGE: { attachImage(); break; }
                    	case ATTACH_AUDIO: { attachAudio(); break; }
                    	case ATTACH_VIDEO: { attachVideo(); break; }
                    	case ATTACH_FILE: { attachFile(); break; }
                    }
                }
    	    });
        	return iconContextMenu_attachment.createMenu(res, "Attachment");
        }
    	
    	
    	
    	if(id == CONTEXT_MENU_ATTACHMENT_LIST_ID) {
    		if(iconContextMenu_attachment_list==null) {
    			iconContextMenu_attachment_list = new IconContextMenu(this, CONTEXT_MENU_ATTACHMENT_LIST_ID);
    		}
    	    iconContextMenu_attachment_list.setOnClickListener(new IconContextMenu.IconContextMenuOnClickListener() {
//    	    	@Override
                public void onClick(int menuId) {
                	if(extra_content_array.length==1) {
                		extra_content = null;
                		extra_type = null;
                		extra_content_array = null;
                		extra_type_array = null;
                		
                		attachmentsSize = null;
                		usedSpace = CONTENT_FIXED_PART_LENGTH + MAX_TITLE_LENGTH + MAX_CONTENT_LENGTH;
                		
                		iconContextMenu_attachment_list = null;
                	}
                	else {
                		extra_content = null;
                		extra_type = null;
                		
                		long[] sizeArrayTmp = new long[attachmentsSize.length];
                		for(int i=0; i<attachmentsSize.length; i++) {
                			sizeArrayTmp[i] = attachmentsSize[i];
                		}
                		
                		attachmentsSize = new long[sizeArrayTmp.length-1];
                		int ii = 0;
                		for(int i=0; i<extra_content_array.length; i++) {
                			if(i!=menuId) {
                				if(extra_content != null) {
                		    		extra_content = extra_content + "," + extra_content_array[i];
                		    		extra_type = extra_type + "," + extra_type_array[i];
                		    	}
                		    	else {
                		    		extra_content = extra_content_array[i];
                		    		extra_type = extra_type_array[i];
                		    	}
                				attachmentsSize[ii] = sizeArrayTmp[i];
                				ii++;
                			}
                		}
                		extra_content_array = extra_content.split(",");
                		extra_type_array = extra_type.split(",");
                		usedSpace = CONTENT_FIXED_PART_LENGTH + MAX_TITLE_LENGTH + MAX_CONTENT_LENGTH;
                		for(long item:attachmentsSize) {
                			usedSpace = usedSpace + item;
                		}
                		
                		iconContextMenu_attachment_list.removeItem(menuId);
                	}
                }
    	    });
        	return iconContextMenu_attachment_list.createMenu(res, "Remove an attachment");
        }
    	
    	
    	
    	if(id == DIALOG_TITLE) {
    		if(dialogTitle==null) {
	            dialogTitle = new Dialog(this);
				dialogTitle.setContentView(R.layout.enter_title_dialog);
				dialogTitle.setTitle("Set title");
	            
	            msg_title_ET = (EditText)dialogTitle.findViewById(R.id.message_title_ET); 
	    		dialogTitleDismissButton = (Button)dialogTitle.findViewById(R.id.dialogTitleDismissButton);
	    		
	    		dialogTitleDismissButton.setOnClickListener(this);
	    	}
    		return dialogTitle;
        }
    	
    	
    	if(id == CONTEXT_MENU_LOCATION_ID) {
    		if(iconContextMenu_location==null) {
    		    iconContextMenu_location = new IconContextMenu(this, CONTEXT_MENU_LOCATION_ID);
    		    iconContextMenu_location.addItem(res, "Deferred sending", R.drawable.icon, DEFERRED_LOCATION);
    		    iconContextMenu_location.addItem(res, "Send without location", R.drawable.icon, WITHOUT_LOCATION);
    		    iconContextMenu_location.addItem(res, "Send with default location", R.drawable.icon, DEFAULT_LOCATION);
    		    Location lastLocation = null;
				try {
					lastLocation = (Location) mILocationEpicService.getLastKnownLocation();
				} 
				catch (RemoteException e) {
					e.printStackTrace();
				}
    		    if(lastLocation!=null) {
    		    	last_altitude = lastLocation.getAltitude();
    		    	last_latitude = lastLocation.getLatitude();
    		    	last_longitude = lastLocation.getLongitude();
    		    	String lastLocationDate = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(lastLocation.getTime());
    		    	iconContextMenu_location.addItem(res, "Send with last known location: " +
    		    			lastLocationDate, R.drawable.icon, LAST_LOCATION);
    		    }
        	}
    	    iconContextMenu_location.setOnClickListener(new IconContextMenu.IconContextMenuOnClickListener() {
//    	    	@Override
                public void onClick(int menuId) {
    	    		switch(menuId) {
                    	case DEFERRED_LOCATION: { 
                    		deferred_sending = 1;
	                		msg_altitude = 0; msg_latitude = 0; msg_longitude = 0;
	                		currentAlt = 0; currentLat = 0; currentLon = 0;
	                		setEpicNote();
                    		break; 
                    	}
                    	case WITHOUT_LOCATION: { 
                    		deferred_sending = 0; 
	                		msg_altitude = 0; msg_latitude = 0; msg_longitude = 0;
	                		currentAlt = 0; currentLat = 0; currentLon = 0;
	                		setEpicNote(); 
                    		break; 
                    	}
                    	case DEFAULT_LOCATION: {
                    		CurrentUser.readCurrentUserSettings(getApplicationContext());
                            default_latitude = CurrentUser.getDefaultMsgLatitude();
                            default_longitude = CurrentUser.getDefaultMsgLongitude();
                            default_altitude = CurrentUser.getDefaultMsgAltitude();
                            deferred_sending = 0; 
	                		msg_altitude = default_altitude; msg_latitude = default_latitude; msg_longitude = default_longitude;
	                		currentAlt = default_altitude; currentLat = default_latitude; currentLon = default_longitude;
	                		setEpicNote();
                    		break; 
                    	}
                    	case LAST_LOCATION: { 
                    		deferred_sending = 0; 
	                		msg_altitude = last_altitude; msg_latitude = last_latitude; msg_longitude = last_longitude;
	                		currentAlt = last_altitude; currentLat = last_latitude; currentLon = last_longitude;
	                		setEpicNote();
                    		break; 
                    	}
                    }
                }
    	    });
        	return iconContextMenu_location.createMenu(res, "Location not available!\nChoose how to localize it");
    	}
    	
        return super.onCreateDialog(id);
    }
	
	
	//###############
	// SHOW DIALOGS #
	//###############
	public void showCategoriesDialog() {
		showDialog(DIALOG_CATEGORIES);
	}
	
	public void showGeoDialog() {
		showDialog(DIALOG_GEO);
	}
	
	public void showTimeDialog() {
		showDialog(DIALOG_TIME);
	}
	// the callback received when the user "sets" the date in the dialog
    private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
    	public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
    		expire_year = year;
            expire_month = monthOfYear;
            expire_day = dayOfMonth;
            
            setExpireTime();
        }
    };
	// method called after DatePickerDialog callback 
	private void setExpireTime() {
		Date date = new Date();
		long max_expire_time_in_seconds = date.getTime()/1000 + MAX_EXPIRATION_OFFSET_IN_SECONDS;
		
        calendar.set(expire_year, expire_month, expire_day, 23, 59, 59);
        expire_time_in_millis = calendar.getTimeInMillis();
        expire_time_in_seconds = expire_time_in_millis/1000;
        
        if(max_expire_time_in_seconds<expire_time_in_seconds) {
        	Toast.makeText(getApplicationContext(), "Not possible to set this expiration time! \n" +
        			"Expiration time setted: " + (MAX_EXPIRATION_OFFSET_IN_SECONDS/(60*60*24)) + " days from now", Toast.LENGTH_LONG).show();
        }
    }
	
	public void showAttachmentMenu() {
    	showDialog(CONTEXT_MENU_ATTACHMENT_ID);
    }
	
	
	public void showAttachmentList() {
    	showDialog(CONTEXT_MENU_ATTACHMENT_LIST_ID);
    }
	
	public void showLocationMenu() {
		showDialog(CONTEXT_MENU_LOCATION_ID);
	}
	
	//#################
    //## OPTION MENU ##
    //#################
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
	    MenuInflater inflater = getMenuInflater();
	    inflater.inflate(R.menu.epiccreatemsg_menu, menu);
	    return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
	    // Handle item selection
	    switch (item.getItemId()) {
	    case R.id.epiccreatemsg_menu_set_title:	 
			showDialog(DIALOG_TITLE);
	        return true;
	    case R.id.epiccreatemsg_menu_help:
	        showHelp();
	        return true;
	    default:
	        return super.onOptionsItemSelected(item);
	    }
	}
	
	public void showHelp() {
		Toast.makeText(getApplicationContext(), "Long click on attachment button:\n" +
				"show the list of attachments.\n" +
				"Click on item to remove attachment.", Toast.LENGTH_LONG).show();
	}
	
	// check if there is data connection
	public boolean isOnline() {
		ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo ni = cm.getActiveNetworkInfo();
		if(ni != null){
			return cm.getActiveNetworkInfo().isConnectedOrConnecting();
		}
		else {
			return false;
		}
	}
	
}